package org.yuanqiframework.yuanqi.boot.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.yuanqiframework.yuanqi.web.exception.BusinessException;
import org.yuanqiframework.yuanqi.core.utils.BeanUtils;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysMenu;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysMenuMapper;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysRoleMapper;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysRoleMenuMapper;
import org.yuanqiframework.yuanqi.boot.sys.service.SysMenuService;
import org.yuanqiframework.yuanqi.boot.sys.vo.MenuVO;
import org.yuanqiframework.yuanqi.boot.sys.vo.PageMenuMetaVO;
import org.yuanqiframework.yuanqi.boot.sys.vo.PageMenuVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author cbt28
 * @description 针对表【sys_menu(菜单权限表)】的数据库操作Service实现
 * @createDate 2025-08-18 22:29:33
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>
        implements SysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;


    @Override
    public List<MenuVO> selectMenuList() {
        List<SysMenu> sysMenus = sysMenuMapper.selectList(null);
        List<MenuVO> menuVOS = BeanUtils.copyListProperties(sysMenus, MenuVO::new);
        List<MenuVO> m = menuVOS.stream().filter(menuVO -> menuVO.getMenuType().equals("M") && 0 == menuVO.getParentId())
                .sorted(Comparator.comparingInt(MenuVO::getOrderNum)).collect(Collectors.toList());
        m.forEach(menuVO -> {
            findChildrenMenu(menuVO, menuVOS);
        });
        return m;
    }

    @Override
    public List<PageMenuVO> roleMenu() {
        List<MenuVO> menuVOS = selectMenuList();
        return convert(menuVOS);
    }

    @Override
    public List<PageMenuVO> roleMenu(Set<String> roles) {
        List<String> roleIds = sysRoleMapper.selectIds(roles);
        List<Long> sysRoleMenuIds = sysRoleMenuMapper.selectMenuIds(roleIds);
        List<MenuVO> menuVOS = selectMenuList();
        List<MenuVO> resultList = new LinkedList<>();
        for (MenuVO menuVO : menuVOS) {
            LinkedList<MenuVO> list = new LinkedList<>();
            List<MenuVO> children = menuVO.getChildren();
            for (MenuVO child : children) {
                Long menuId = child.getMenuId();
                if (sysRoleMenuIds.contains(menuId)) {
                    list.add(child);
                }
            }
            if (!list.isEmpty()) {
                menuVO.setChildren(list);
                resultList.add(menuVO);
            }
        }
        return convert(resultList);
    }


    @Override
    public int safeDeleteById(Long id) {
        if (sysMenuMapper.selectCount(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, id)) > 0) {
            throw new BusinessException("该菜单下有子菜单，不能删除！");
        }
        return sysMenuMapper.deleteById(id);
    }

    //List<MenuVO>转化为List<PageMenuVO>
    private List<PageMenuVO> convert(List<MenuVO> menuVOS) {
        if (menuVOS == null) {
            return null;
        }
        return menuVOS.stream().map(this::menuVOToPageMenuVO).collect(Collectors.toList());
    }

    private PageMenuVO menuVOToPageMenuVO(MenuVO menuVO) {
        if (menuVO == null) {
            return null;
        }

        PageMenuVO pageMenuVO = new PageMenuVO();
        pageMenuVO.setName(menuVO.getRouteName());
        pageMenuVO.setPath(menuVO.getPath());
        pageMenuVO.setComponent(menuVO.getComponent());

        // 创建并设置meta对象
        PageMenuMetaVO meta = new PageMenuMetaVO();
        meta.setTitle(menuVO.getMenuName());
        meta.setIcon(menuVO.getIcon());
        meta.setKeepAlive(menuVO.getIsCache() != null && menuVO.getIsCache() == 0);
        meta.setQuery(menuVO.getQuery());
        meta.setIsFrame(menuVO.getIsFrame() != null && menuVO.getIsFrame() == 0);
        meta.setIsCache(menuVO.getIsCache() != null && menuVO.getIsCache() == 0);
        meta.setMenuType(menuVO.getMenuType());
        meta.setVisible("0".equals(menuVO.getVisible()));
        meta.setStatus(menuVO.getStatus());
        meta.setPerms(menuVO.getPerms());
        meta.setRemark(menuVO.getRemark());

        pageMenuVO.setMeta(meta);

        // 递归处理子菜单
        if (menuVO.getChildren() != null) {
            pageMenuVO.setChildren(convert(menuVO.getChildren()));
        }

        return pageMenuVO;
    }


    //递归 List<MenuVO>
    private void findChildrenMenu(MenuVO parentMenu, List<MenuVO> allMenus) {
        List<MenuVO> children = allMenus.stream()
                .filter(menu -> parentMenu.getMenuId().equals(menu.getParentId()))
                .sorted(Comparator.comparingInt(MenuVO::getOrderNum))
                .collect(Collectors.toList());
        parentMenu.setChildren(children);
        if (!children.isEmpty()) {
            for (MenuVO child : children) {
                findChildrenMenu(child, allMenus);
            }
        }
    }
}




